using System;
using FM_Mono;
using UnityEngine;

/**
  * Unity3D's TouchScreenKeyboard is flawed, here's our own implementation to make up its shortcomings while having a similar API.
  * 
  * @author SamuliPiela / One Digit Ltd
  */
[IgnoreGen]
public class AndroidKeyboard : MonoBehaviour
{
    public event Action onSendButtonClickEvent;

    string _className = "com.android.keyboard.AndroidKeyboard";
    string _methodOpen = "open";
    string _methodClose = "close";
    string _methodIsDone = "isDone";
    string _methodIsCanceled = "isCanceled";
    string _methodIsOpen = "isOpen";
    string _methodIsVisible = "isVisible";
    string _methodGetText = "getText";
    string _methodSetText = "setText";
    string _methodGetKeyboardHeight = "getKeyboardHeight";
    string _methodSetInputAndSendBtnLayout = "setInputAndSendBtnLayout";
    
    int _keyboardHeight = 0;

    private static AndroidKeyboard _instance = null;

	public static int standardScreenHeight
	{
		get
		{
			if(Screen.width > Screen.height)
			{
				return 640;
			}

			return 1136;
		}
	}

    public static AndroidKeyboard instance
    {
        get
        {
            if (_instance == null)
            {
                GameObject obj = new GameObject("AndroidKeyboard");
                _instance = obj.AddComponent<AndroidKeyboard>();
                DontDestroyOnLoad(obj);
            }
            return _instance;
        }
    }

    /**
      * true if the keyboard is not open, false if the keyboard is still open
      */
    public bool IsDone { get {
            return _IsDone();
        }
    }
    
    /**
      * true if the keyboard has gone away without the end-user hitting the action button first.
      */
    public bool IsCanceled { get {
            return _IsCanceled();
        }
    }

    public bool IsOpen { get {
            return _IsOpen();
        }
    }

    public bool IsVisible { get {
            return _IsVisible();
        }
    }
    
    /**
      * The text that is currently being input or if the keyboard is not open, the last inputted text
      */
    public string Text { get {
            return _GetText();
        }
        set {
            _SetText(value);
        }
    }

    public int KeyboardHeight { get {
	    //if (_keyboardHeight == 0)
	    {
		    _keyboardHeight = _GetKeyboardHeight();

		    _keyboardHeight = (int) (standardScreenHeight * (float) _keyboardHeight / Screen.height);
	    }
            return _keyboardHeight;
//            return 500;
        }
    }
    
    public void Open(/*string defaultText*/)
    {
        using (AndroidJavaClass jc = new AndroidJavaClass(_className)) {
            jc.CallStatic(_methodOpen);

//	        AndroidJavaObject singleObj = jc.GetStatic<AndroidJavaObject>("instance");
//	        singleObj.Set<string>("lastKnownInputText", defaultText);
//	        singleObj.Dispose();
//
//	        Debug.Log(Text);
        }

    }
    
    public void Close()
    {
        using (AndroidJavaClass jc = new AndroidJavaClass(_className)) {
            jc.CallStatic(_methodClose);
        }
    }

    public void SetInputAndSendBtnLayout(float leftPadding, float inputAreaWidth, float sendBtnWidth, float rightPadding, float inputAreaHeight)
    {
        using (AndroidJavaClass jc = new AndroidJavaClass(_className)) {
            jc.CallStatic(_methodSetInputAndSendBtnLayout, new object[] { leftPadding, inputAreaWidth, sendBtnWidth, rightPadding, inputAreaHeight });
        }
    }
    
    private void OnSendButtonClick()
    {
        if(onSendButtonClickEvent != null)
        {
            onSendButtonClickEvent();
        }
    }
    
    private bool _IsDone()
    {
        using (AndroidJavaClass jc = new AndroidJavaClass(_className)) {
            return jc.CallStatic<bool>(_methodIsDone);
        }
    }
    
    private bool _IsCanceled()
    {
        using (AndroidJavaClass jc = new AndroidJavaClass(_className)) {
            return jc.CallStatic<bool>(_methodIsCanceled);
        }
    }

    private bool _IsOpen()
    {
        using (AndroidJavaClass jc = new AndroidJavaClass(_className)) {
            return jc.CallStatic<bool>(_methodIsOpen);
        }
    }

    private bool _IsVisible()
    {
        using (AndroidJavaClass jc = new AndroidJavaClass(_className)) {
            return jc.CallStatic<bool>(_methodIsVisible);
        }
    }
    
    private string _GetText()
    {
        using (AndroidJavaClass jc = new AndroidJavaClass(_className)) {
            return jc.CallStatic<string>(_methodGetText);
        }
    }

    private void _SetText(string text)
    {
        using (AndroidJavaClass jc = new AndroidJavaClass(_className)) {
            jc.CallStatic(_methodSetText, text);
        }
    }

    private int _GetKeyboardHeight()
    {
        using (AndroidJavaClass jc = new AndroidJavaClass(_className)) {
            return jc.CallStatic<int>(_methodGetKeyboardHeight);
        }
    }

    private void OnDestroy()
    {
        onSendButtonClickEvent = null;
    }
}